package gateway.config.security.login;

import cn.hutool.json.JSONUtil;
import common.config.http.HttpStatusEnum;
import common.config.rocketmq.MqTaskEnum;
import common.config.rocketmq.producer.SystemLogMqProducer;
import common.model.po.SysLog;
import common.model.response.base.Result;
import common.util.IpUtils;
import common.util.ResponseUtil;
import gateway.config.security.util.StopWatchUtil;
import gateway.model.converter.SecurityConverter;
import gateway.model.dto.SecurityUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 登录成功处理
 *
 * @author 米泽鹏
 * @since 2021-07-31 4:58 下午
 */
@Component
@Slf4j
public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

	@Resource
	private SystemLogMqProducer systemLogMqProducer;
	@Value("${spring.application.name}")
	private String appName;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
		SysLog sysLog = null;
		try {
			SecurityUser securityUser = ((SecurityUser) authentication.getPrincipal());
			ResponseUtil.out(response, Result.success("登录成功", SecurityConverter.securityUserToUserVo(securityUser)));
			// 日志
			sysLog = new SysLog();
			sysLog.setOperator(securityUser.getUsername());
			sysLog.setMethodName("login");
			sysLog.setMethodDescription("登录");
			sysLog.setRequestUrl(request.getRequestURI().replace(request.getContextPath(), ""));
			sysLog.setIp(IpUtils.getIpAddress(request));
			sysLog.setStatusCode(HttpStatusEnum.SUCCESS.getCode());
			sysLog.setMessage(HttpStatusEnum.SUCCESS.getMessage());
			sysLog.setExecutionDate(new Date());
			// 执行耗时
			Long loginStartTime = StopWatchUtil.LOGIN_START_TIME.get();
			sysLog.setExecutionTime(System.currentTimeMillis() - loginStartTime);
			// RocketMQ单向消息：记录系统日志
			Message msg = new Message(MqTaskEnum.SYSTEM_LOG.getTopic(), appName, JSONUtil.toJsonStr(sysLog).getBytes(RemotingHelper.DEFAULT_CHARSET));
			systemLogMqProducer.sendOneway(msg);
			log.info("已发送RocketMQ单向消息：系统日志，来自服务：" + appName);
		} catch (MQClientException | RemotingException | InterruptedException e) {
			log.error("发送RocketMQ单向消息失败：系统日志，来自服务：{}，日志详情：{}", appName, JSONUtil.toJsonPrettyStr(sysLog), e);
		} catch (Exception e) {
			log.error("CustomAuthenticationSuccessHandler.onAuthenticationSuccess()发生异常", e);
		} finally {
			StopWatchUtil.LOGIN_START_TIME.remove();
		}
	}

}
